package com.leadingsoft.pwxk.service.impl;

import java.io.IOException;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import javax.persistence.EntityManager;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.leadingsoft.pwxk.dto.SearchDto;
import com.leadingsoft.pwxk.enums.SheetEnum;
import com.leadingsoft.pwxk.excel.ExcelUtil;
import com.leadingsoft.pwxk.model.FillYearPlan;
import com.leadingsoft.pwxk.model.QBaseInfo;
import com.leadingsoft.pwxk.model.QLatestData;
import com.leadingsoft.pwxk.model.QLicenseInfo;
import com.leadingsoft.pwxk.model.QPwBaseInfo;
import com.leadingsoft.pwxk.model.QRegionCode;
import com.leadingsoft.pwxk.model.QYearPlan;
import com.leadingsoft.pwxk.model.RegionCode;
import com.leadingsoft.pwxk.model.YearPlan;
import com.leadingsoft.pwxk.repository.FillYearPlanRepository;
import com.leadingsoft.pwxk.repository.RegionCodeRepository;
import com.leadingsoft.pwxk.repository.YearPlanRepository;
import com.leadingsoft.pwxk.service.YearPlanService;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.Tuple;
import com.querydsl.jpa.impl.JPAQuery;

@Service
public class YearPlanServiceImpl implements YearPlanService {

	QYearPlan qYearPlan = QYearPlan.yearPlan;

	@Autowired
	EntityManager em;

	@Autowired
	YearPlanRepository yearPlanRepository;

	@Autowired
	FillYearPlanRepository fillYearPlanRepository;

	@Autowired
	RegionCodeRepository regionCodeRepository;

	QBaseInfo qBaseInfo = QBaseInfo.baseInfo;

	QLicenseInfo qLicenseInfo = QLicenseInfo.licenseInfo;

	QPwBaseInfo qPwBaseInfo = QPwBaseInfo.pwBaseInfo;

	QRegionCode qRegionCode = QRegionCode.regionCode1;

	QLatestData qLatestData = QLatestData.latestData;

	@Transactional
	@Override
	public Map<String, Object> importData(MultipartHttpServletRequest request) throws IOException {
		Iterator<String> filenames = request.getFileNames();
		Map<String, Object> map = new HashMap<String, Object>();
		while (filenames.hasNext()) {
			MultipartFile file = request.getFile(filenames.next());
			// 解析数据为map <行号,数据内容>
			List<Map<Integer, List<String>>> datas = ExcelUtil.parseExcel(file, 1, 8);
			// 数据校验
			List<Map<String, Object>> validateData = validateData(datas);
			if (!validateData.isEmpty() && validateData.size() > 0) {
				map.put("succ", false);
				map.put("error", validateData);
				return map;
			}
			for (Map<Integer, List<String>> t : datas) {
				if (t.size() <= 1) {
					continue;
				}
				List<YearPlan> list = new ArrayList<YearPlan>();
				FillYearPlan fillYearPlan = new FillYearPlan();
				List<String> lastData = t.get(-1);
				String[] split;
				if (lastData.get(0).indexOf(":") != -1) {
					split = lastData.get(0).split(":");
				} else {
					split = lastData.get(0).split("：");
				}
				fillYearPlan.setFillPerson(split[1].replace("联系方式", "").trim());
				fillYearPlan.setLinkWay(split[2].replace("填报单位", "").trim());
				fillYearPlan.setUnit(split[3].replace("填报日期", "").trim());
				Integer year = 0;
				if (split.length >= 5) {
					String time = split[4].trim();
					if (StringUtils.isBlank(time)) {
						map.put("succ", false);
						map.put("error", "填报日期不能为空");
						return map;
					} else {
						try {
							DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
							formatter.parse(time);
							year = Integer.parseInt(time.substring(0, time.indexOf("-")));
						} catch (Exception e) {
							map.put("succ", false);
							map.put("error", "填报日期格式不正确");
							return map;
						}
					}
					fillYearPlan.setFileDate(split[4].trim());
				}
				for (Entry<Integer, List<String>> entry : t.entrySet()) {
					if (entry.getKey() != -1) {
						YearPlan yearPlan = new YearPlan();
						yearPlan.setRegionName(entry.getValue().get(3));
						yearPlan.setDevcompany(entry.getValue().get(1));
						yearPlan.setHyname(entry.getValue().get(2));
						yearPlan.setProductaddress(entry.getValue().get(4));
						yearPlan.setSocietycode(entry.getValue().get(5));
						yearPlan.setLinkMan(entry.getValue().get(6));
						yearPlan.setTel(entry.getValue().get(7));
						yearPlan.setRemark(entry.getValue().get(8));
						yearPlan.setYear(year.toString());
						list.add(yearPlan);
					}
				}
				yearPlanRepository.saveAll(list);
				fillYearPlan.setYearPlan(list);
				fillYearPlanRepository.save(fillYearPlan);
			}
		}
		map.put("succ", true);
		return map;
	}

	@Override
	public Page<YearPlan> list(Pageable pageable, SearchDto s) {
		BooleanBuilder booleanBuilder = new BooleanBuilder();
		if (StringUtils.isNotBlank(s.getYear())) {
			booleanBuilder.and(qYearPlan.year.eq(s.getYear()));
		}
		if (StringUtils.isNotBlank(s.getCodeRegion())) {
			booleanBuilder.and(qYearPlan.regionName.containsIgnoreCase(s.getCodeRegion()));
		}
		if (StringUtils.isNoneBlank(s.getDevcompany())) {
			booleanBuilder.and(qYearPlan.devcompany.containsIgnoreCase(s.getDevcompany())
					.or(qYearPlan.hyname.containsIgnoreCase(s.getDevcompany())));
		}
		return yearPlanRepository.findAll(booleanBuilder.getValue(), pageable);
	}

	private boolean hasFillInfo(String data) {
		if (data != null
				&& (data.indexOf("填报人：") == -1 && data.indexOf("联系方式：") == -1 && data.indexOf("填报单位：") == -1
						&& data.indexOf("填报日期：") == -1)
				|| (data.indexOf("填报人:") == -1 && data.indexOf("联系方式:") == -1 && data.indexOf("填报单位:") == -1
						&& data.indexOf("填报日期:") == -1)) {
			return false;
		} else {
			return true;
		}
	}

	private List<Map<String, Object>> validateData(List<Map<Integer, List<String>>> data) {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		for (int i = 0; i < data.size(); i++) {
			Map<Integer, List<String>> temp = data.get(i);
			if (!temp.isEmpty()) {
				List<String> lastData = temp.get(-1);
				if (lastData.isEmpty() || hasFillInfo(lastData.get(0))) {
					Map<String, Object> fillMap = new HashMap<String, Object>();
					fillMap.put(SheetEnum.getByOrder(i).getDesc(), "导入execl不包含填报人等信息");
					list.add(fillMap);
				}
				for (Entry<Integer, List<String>> entry : temp.entrySet()) {
					Integer key = entry.getKey();
					List<String> val = entry.getValue();
					if (key != -1) {
						List<RegionCode> regionName = regionCodeRepository.findByRegionName(repalaceName(val.get(3)));
						if (regionName.size() == 0) {
							Map<String, Object> cityMap = new HashMap<String, Object>();
							cityMap.put(SheetEnum.getByOrder(i).getDesc(), "第" + key + "导入市州数据异常");
							list.add(cityMap);
						}
					}
				}
			}
		}
		return list;
	}

	@Override
	public List<Map<String, Object>> getStatistical(String year) {
		JPAQuery<Tuple> query = new JPAQuery<Tuple>(em);
		query.select(qYearPlan.id.count(), qYearPlan.regionName, qRegionCode.regionCode);
		query.from(qYearPlan).leftJoin(qRegionCode).on(qYearPlan.regionName.eq(qRegionCode.regionName));
		if (StringUtils.isNoneBlank(year)) {
			query.where(qYearPlan.year.eq(year));
		}
		query.groupBy(qYearPlan.regionName, qRegionCode.regionCode);
		query.orderBy(qRegionCode.regionCode.asc());
		JPAQuery<Tuple> query2 = new JPAQuery<Tuple>(em);
		query2.select(qBaseInfo.enterid, qBaseInfo.name_region);
		query2.from(qLatestData).leftJoin(qLicenseInfo).on(qLatestData.dataid.eq(qLicenseInfo.dataid));
		query2.leftJoin(qPwBaseInfo).on(qLicenseInfo.dataid.eq(qPwBaseInfo.dataid)).leftJoin(qBaseInfo)
				.on(qBaseInfo.enterid.eq(qPwBaseInfo.enterid));
		if (StringUtils.isNoneBlank(year)) {
			query2.where(qLicenseInfo.fztime.substring(0, qLicenseInfo.fztime.indexOf("-")).eq(year));
		}
		List<Tuple> fetch = query.fetch();
		List<Tuple> fetch2 = query2.fetch();
		Map<String, String> distinctMap = new LinkedHashMap<String, String>();
		Set<String> nameSet = new LinkedHashSet<String>();
		fetch2.forEach(t -> {
			distinctMap.put(t.get(0, String.class), t.get(1, String.class));
			nameSet.add(t.get(1, String.class));
		});
		List<Map<String, Object>> result = new ArrayList<Map<String,Object>>();
		int count;
		for (String name : nameSet) {
			count = 0;
			for (String val : distinctMap.values()) {
				if (name.equals(val)) {
					count++;
				}
			}
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("name", name);
			map.put("num", count);
			result.add(map);
		}
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		fetch.forEach(t -> {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("sf", 0);
			result.forEach(t2 -> {
				if (t.get(qYearPlan.regionName).equals(t2.get("name"))) {
					map.put("sf", t2.get("num"));
				}
			});
			map.put("key", t.get(qYearPlan.regionName));
			map.put("hf", t.get(qYearPlan.id.count()));
			list.add(map);
		});
		return list;
	}

	private String repalaceName(String val) {
		switch (val) {
		case "阿坝州":
			return "阿坝藏族羌族自治州";
		case "甘孜州":
			return "甘孜藏族自治州";
		case "凉山州":
			return "凉山彝族自治州";
		default:
			return val;
		}
	}

}
